package com.fount4j.generator.introspector;

import com.fount4j.generator.config.TableConfig;
import com.fount4j.generator.constant.GeneratorConstants;
import com.fount4j.generator.context.GeneratorContext;
import com.fount4j.generator.exception.GenerateException;
import com.fount4j.generator.introspector.DataSourceIntrospector;
import com.fount4j.generator.introspector.FileIntrospector;
import com.fount4j.generator.util.GeneratorFileUtils;
import com.fount4j.generator.util.JdbcUtils;
import org.beetl.core.Template;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.List;

/**
 * 生成器主类
 *
 * @author Morven 2016/12/20
 */
public class Generator {
    /** 生成器上下文 */
    protected GeneratorContext context;

    public Generator(GeneratorContext context) {
        this.context = context;
    }

    public void generate() {
        List<TableConfig> tables = context.getTables();
        if (tables == null || tables.isEmpty()) {
            return;
        }

        Connection con = null;
        try {
            con = getConnection();
            DatabaseMetaData metaData = con.getMetaData();
            for (TableConfig tableConfig : tables) {
                context.setTableConfig(tableConfig);
                context.getTableIntrospector().introspectTable(context, metaData);
                generateFiles();
            }
        } catch (SQLException e) {
            throw new GenerateException("获取数据库元数据出错", e);
        } catch (IOException e) {
            throw new GenerateException("生成文件出错", e);
        } finally {
            JdbcUtils.close(con);
        }
    }

    protected void generateFiles() throws IOException {
        List<FileIntrospector> introspectors = context.getIntrospectors();
        if (introspectors == null || introspectors.isEmpty()) {
            return;
        }
        for (FileIntrospector fi : introspectors) {
            if (fi.isGenerateEnable()) {
                String infoKey = fi.getInfoKey();
                Template template = context.getTemplate(infoKey);
                template.binding(context.getInfoMap());
                template.binding("table", context.getTableInfo());
                String content = template.render();
                GeneratorFileUtils.writeStringToFile(context.getInfo(infoKey).getFile(), content,
                        GeneratorConstants.GLOBAL_ENCODING);
            }
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库 JDBC 连接
     */
    protected Connection getConnection() {
        DataSourceIntrospector dataSourceIntrospector = context.getDataSourceIntrospector();
        if (dataSourceIntrospector == null) {
            throw new GenerateException("没有配置数据库连接");
        }
        return dataSourceIntrospector.getConnection(context);
    }

}
